package com.wuzhun.wxmp.interceptor;

import com.wuzhun.wxmp.annotation.LoginRequired;
import com.wuzhun.wxmp.annotation.PageLoginRequired;
import com.wuzhun.wxmp.common.ResultCode;
import com.wuzhun.wxmp.common.ServiceException;
import com.wuzhun.wxmp.constant.CommonConstant;
import com.wuzhun.wxmp.service.ITokenService;
import com.wuzhun.wxmp.util.CookieUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 *
 * @author baolin
 * @date 2022/12/03 14:24 下午
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptor.class);

    @Value("${wuzhun.domain}")
    private String domain;

    @Resource
    private ITokenService tokenService;

    /**
     * 请求处理之后
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

    /**
     * 请求处理之后调用
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }


    /**
     * 请求处理之前调用
     *
     * @param request
     * @param response
     * @param handler
     * @return
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 如果不是映射到方法直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 判断接口是否需要登录
        LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
        // 判断页面是否需要登录
        PageLoginRequired pageLoginRequired = method.getAnnotation(PageLoginRequired.class);
        // 有 @LoginRequired 注解，需要认证
        if (loginRequired != null || pageLoginRequired != null) {
            boolean tokenStatus;
            // 执行认证
            String token = request.getHeader(CommonConstant.TOKEN_KEY);  // 从 http 请求头中取出 token
            if (StringUtils.isEmpty(token)) {
                token = CookieUtil.getCookie(request, CommonConstant.TOKEN_KEY);
            }
            int tokenLength = 32;
            if (loginRequired != null && StringUtils.isEmpty(token)) {
                throw new ServiceException(ResultCode.USER_NOT_LOGIN);
            } else if (loginRequired != null && token.length() != tokenLength) {
                throw new ServiceException(ResultCode.INVALID_TOKEN);
            } else {
                tokenStatus = tokenService.verifyToken(token);
                if (loginRequired != null && !tokenStatus) {
                    throw new ServiceException(ResultCode.LOGIN_EXPIRED);
                }
            }
            if (StringUtils.isEmpty(token) || token.length() != tokenLength || !tokenStatus) {
                try {
                    response.sendRedirect(domain + "admin/user/login");
                } catch (IOException e) {
                    LOGGER.error("AuthInterceptor pageLoginRequired error", e);
                }
            }
            String lastActiveTimeStr = CookieUtil.getCookie(request, CommonConstant.LAST_ACTIVE_TIME_KEY);
            // 活跃校验
            long lastActiveTime = 0;
            if (StringUtils.isNotEmpty(lastActiveTimeStr)){
                lastActiveTime = Long.parseLong(lastActiveTimeStr);
            }
            if (lastActiveTime < System.currentTimeMillis() - CommonConstant.THIRTY_MINUTE_MILLS) {
                try {
                    CookieUtil.deleteCookie(response, CommonConstant.USERNAME_KEY);
                    CookieUtil.deleteCookie(response, CommonConstant.TOKEN_KEY);
                    response.sendRedirect(domain + "admin/user/login");
                } catch (Exception e) {
                    LOGGER.error("AuthInterceptor delete cookie error ", e);
                }
            }
            CookieUtil.setCookie(response, CommonConstant.LAST_ACTIVE_TIME_KEY, String.valueOf(System.currentTimeMillis()), CommonConstant.THIRTY_MINUTE_MILLS);
            return true;
        }
        return true;
        // return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}